package com.fastloan.mgt.product.basics.service.impl;

import com.fastloan.common.BasicServiceImpl;
import com.fastloan.mgt.application.base.util.CodeUtil;
import com.fastloan.mgt.dictionary.model.Dictionary;
import com.fastloan.mgt.dictionary.service.DictionaryService;

import com.fastloan.mgt.expert.service.ExpertService;
import com.fastloan.mgt.home.service.HomeConfigService;

import com.fastloan.mgt.model.service.ModelCalculateService;
import com.fastloan.mgt.product.approve.service.ProductApproveService;
import com.fastloan.mgt.product.basics.dao.ProductMapper;
import com.fastloan.mgt.product.basics.model.Product;
import com.fastloan.mgt.product.basics.model.ProductFile;
import com.fastloan.mgt.product.basics.model.vo.ProductHotExt;
import com.fastloan.mgt.product.basics.model.vo.ProductVO;
import com.fastloan.mgt.product.basics.service.ProductConditionsService;
import com.fastloan.mgt.product.basics.service.ProductFileService;
import com.fastloan.mgt.product.basics.service.ProductService;
import com.fastloan.mgt.product.basics.service.ProductTempService;
import com.fastloan.mgt.product.expection.ProductApproveException;
import com.fastloan.mgt.product.flow.service.ProductFlowService;
import com.fastloan.mgt.product.label.service.LabelService;
import com.fastloan.mgt.product.postloan.service.ProductPostLoanService;
import com.fastloan.mgt.sequence.model.Sequence;
import com.fastloan.safe.core.util.ManagerKit;
import com.fastloan.safe.mgt.org.model.vo.OrgTreeVo;
import com.fastloan.safe.mgt.org.service.CmuOrgService;
import com.fastloan.safe.mgt.sys.model.CmuSysFile;
import com.fastloan.safe.mgt.sys.service.CmSysFileService;
import com.fastloan.utils.DozerUtil;
import com.kawins.supers.file.core.FileLoadBean;
import com.kawins.supers.table.manager.DataTable;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.*;

import static com.fastloan.mgt.home.service.impl.HomeConfigServiceImpl.DON_T_SHOW;
import static com.fastloan.mgt.home.service.impl.HomeConfigServiceImpl.SHOW;
import static com.fastloan.mgt.product.enums.ProductEnum.FORBIDDEN;
import static com.fastloan.mgt.product.enums.ProductEnum.PUBLISHED;
import static java.util.stream.Collectors.toList;

/**
 * @author admins
 * createTime 2017/11/06
 */
@Service
public class ProductServiceImpl extends BasicServiceImpl<Product> implements ProductService {

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private ProductFileService productFileService;

    @Autowired
    private DictionaryService dictionaryService;

    @Autowired
    private CmSysFileService cmSysFileService;

    @Autowired
    private ProductFlowService productFlowService;

    @Autowired
    private ProductPostLoanService productPostLoanService;

    @Autowired
    private ProductApproveService productApproveService;

    @Autowired
    private ModelCalculateService modelCalculateService;

    @Autowired
    private ProductTempService productTempService;

    @Autowired
    private CmuOrgService cmuOrgService;

    @Autowired
    private ProductConditionsService productConditionsService;

    @Autowired
    private ExpertService expertService;

    @Autowired
    private LabelService labelService;

    @Autowired
    private HomeConfigService homeConfigService;

    @Override
    @Transactional
    public String createProduct(Product product, @PathVariable MultipartFile[] file) {
        product.setCreateTime(new Date());
        product.setProductCode(CodeUtil.getProductCode(product.getOrgId()));
        insertSelective(product);
        List<FileLoadBean> fileLoadBeans = productFileService.uploadProductFile(product.getProductId(), 1, file);
        if (fileLoadBeans.isEmpty()) {
            throw new RuntimeException("文件上传失败");
        }
        updateLogoUrl(fileLoadBeans, product);
        log.debug("新增产品成功, 产品id:{}, 操作用户id:{}, 操作时间{}", product.getProductId(), ManagerKit.getUserId(), LocalDateTime.now());
        return product.getProductId();
    }

    @Override
    public void updateLogoUrl(List<FileLoadBean> fileLoadBeanList, Product product) {
        fileLoadBeanList.forEach(fileLoadBean -> {
            product.setLogoUrl(cmSysFileService.selectByPrimaryKey(fileLoadBean.getFileId()).getUrl());
            updateByPrimaryKeySelective(product);
            log.debug("新增/更新产品Logo, 产品id:{}, 文件id:{}, 操作用户id:{}, 操作时间{}", product.getProductId(), fileLoadBean.getFileId(), ManagerKit.getUserId(), LocalDateTime.now());
        });
    }

    @Override
    @DataTable(name = "productPageList")
    public List<Product> pageList(Map<String, Object> map) {
        return productMapper.pageList(map);
    }

    @Override
    public List<Product> getAllProduct() {
        List<OrgTreeVo> orgTreeVos = cmuOrgService.selectSonByTop(getOrgIdByAdminOrOther(), true, false);
        List<Product> productArrayList = new ArrayList<>();
        for (OrgTreeVo orgTreeVo : orgTreeVos) {
            Product product = new Product();
            product.setOrgId(orgTreeVo.getId());
            // product.setStatus(PUBLISHED.getType());
            List<Product> productList = select(product);
            productArrayList.addAll(productList);
        }
        return productArrayList;
    }

    @Override
    public Long selectSequence(String orgId) {
        Long selectSequence = productMapper.selectSequence(orgId);
        if (selectSequence == 0) {
            Sequence sequence = new Sequence();
            sequence.setSeqName(orgId);
            sequence.setCurrentVal(1);
            sequence.setIncrementVal(1);
            productMapper.insertSequence(sequence);
            log.debug("产品code初始化成功, 机构id:{}, 操作用户id:{}, 操作时间{}", orgId, ManagerKit.getUserId(), LocalDateTime.now());
            return sequence.getCurrentVal().longValue();
        }
        return selectSequence;
    }

    @Override
    public Map<String, Object> getDictionary() {
        List<OrgTreeVo> orgTreeVos = cmuOrgService.selectSonByTop(getOrgIdByAdminOrOther(), true, false);
        Map<String, List<Dictionary>> map = dictionaryService.queryDictionary("product");
        List<OrgTreeVo> orgTreeVoList = orgTreeVos.stream().filter(orgTreeVo -> !orgTreeVo.getParentId().equals("0")
                && !StringUtils.isBlank(orgTreeVo.getParentId())).collect(toList());
        Map<String, Object> maps = new HashMap<>(map);
        maps.put("model", modelCalculateService.getAllModel());
        maps.put("productOrg", orgTreeVoList);
        maps.put("conditions", productConditionsService.selectAll());
        maps.put("approveUsers", expertService.queryAllExpert(ManagerKit.getTopOrgId()));
        maps.put("funding", dictionaryService.queryDictionaryVO("funding"));
        return maps;
    }

    @Override
    public ProductVO getProduct(String productId) {
        Product product = selectByPrimaryKey(productId);
        ProductVO productVO = DozerUtil.map(product, ProductVO.class);
        productVO.setLogos(getProductFile(productId, 1));
        productVO.setProductFiles(getProductFile(productId, 0));
        productVO.setLabelList(labelService.queryByProductId(productId));
        return productVO;
    }

    @Override
    public Integer releaseOrForbidden(String productId) throws ProductApproveException {
        Product product = selectByPrimaryKey(productId);
        if (productFlowService.getProductFlowCount(productId) <= 0) {
            throw new ProductApproveException("未配置贷款流程");
        } else if (productPostLoanService.postLoanCount(productId) <= 0 && product.getProductType().equals(2)) {
            throw new ProductApproveException("未配置贷后监控规则");
        } else if (productTempService.tempCount(productId) <= 0) {
            throw new ProductApproveException("未配置产品IPC调查模板");
        } else if (productFlowService.ifHaveApprove(productId)) {
            if (productApproveService.approveCount(productId) <= 0) {
                throw new ProductApproveException("未配置审批流程");
            }
        }
        if (product.getStatus().equals(PUBLISHED.getType())) {
            product.setStatus(FORBIDDEN.getType());
            homeConfigService.modifyShowConfig(productId, DON_T_SHOW);//禁用产品下架热门应用
        } else {
            product.setStatus(PUBLISHED.getType());
            homeConfigService.modifyShowConfig(productId, SHOW);//启用产品恢复热门产品
        }
        int update = updateByPrimaryKeySelective(product);
        log.debug("产品启用/禁用, 产品id:{}, 操作用户{}, 操作时间{}", productId, ManagerKit.getUserId(), LocalDateTime.now());
        return update;
    }

    private List<CmuSysFile> getProductFile(String productId, int fileType) {
        ProductFile productFile = new ProductFile();
        productFile.setProductId(productId);
        productFile.setType(fileType);
        List<ProductFile> productFiles = productFileService.select(productFile);
        return productFiles.stream()
                .map(sysFileFunction -> cmSysFileService.selectByPrimaryKey(sysFileFunction.getFileId()))
                .collect(toList());
    }

    @DataTable(name = "queryAddressProduce")
    @Override
    public List<ProductHotExt> queryAddressProduce(Map<String, Object> map) {
        return productMapper.queryAddressProduct(map);
    }

    @Override
    public List<ProductHotExt> selectRollingGraph(Map<String, Object> map) {
        return productMapper.selectRollingGraph(map);
    }

    @Override
    public List<ProductHotExt> queryHotSell(Map<String, Object> map) {
        return productMapper.queryHotSell(map);
    }

    @Override
    public List<ProductHotExt> queryByOrg(Map<String, Object> map) {
        return productMapper.queryByOrg(map);
    }
}
